package robot

import (
	"context"
	"encoding/base64"
	"math/rand"
	"strconv"
	"sync"
	"time"

	"device-admin/config/mysql"
	"device-admin/config/redis"
	"device-admin/internal/app/grpc/protoc/devicec"
	"device-admin/internal/app/grpc/protoc/robotc"
	"device-admin/internal/app/grpc/service/common"
	"device-admin/internal/app/grpc/service/pubsub"
	"device-admin/internal/app/grpc/service/terminal"
	"device-admin/internal/app/web/service/device"
	"device-admin/internal/dal"
	"device-admin/internal/dao"
	"device-admin/internal/define"
	"device-admin/internal/models"

	"192.168.1.75/go-pkg/go-cache"
	"192.168.1.75/go-pkg/helper"
	"192.168.1.75/go-pkg/logx"
	"github.com/robfig/cron/v3"
	"github.com/shopspring/decimal"
	"google.golang.org/protobuf/proto"
)

// 设备定时任务
var (
	DeviceCron    = cron.New(cron.WithSeconds())
	DeviceCronIDs sync.Map // map[RobotID][]CronID          每个设备的设备定时器
)

func init() {
	DeviceCron.Start()
}

// InitDeviceCrond 初始化设备定时任务
func InitDeviceSessionCrond(robotID string) {
	RemoveDeviceSessionCron(robotID)
	// 任务实例
	var deviceCronTask DeviceCronTask
	deviceCronTask.RobotID = robotID
	deviceCronTask.ConfigItemTypes = []string{"PPOAC_Params.OA_OBS_RADIUS"}
	// 加载每隔任务，并保存至设备任务map，会话结束时，销毁定时任务
	var entryIDs []cron.EntryID
	entryIDs = append(entryIDs,
		// 获取配置
		func() cron.EntryID {
			r := rand.New(rand.NewSource(time.Now().UnixNano()))
			second := strconv.Itoa(1800 + r.Intn(300))
			entryID, _ := DeviceCron.AddFunc("@every "+second+"s", deviceCronTask.getConfigItem)
			return entryID
		}(),
		// 保存环境因子
		func() cron.EntryID {
			entryID, _ := DeviceCron.AddFunc("@every 5m", deviceCronTask.saveDeviceMetric)
			return entryID
		}(),
		// 热力图位置统计
		func() cron.EntryID {
			r := rand.New(rand.NewSource(time.Now().UnixNano()))
			second := strconv.Itoa(r.Intn(60))
			entryID, _ := DeviceCron.AddFunc(second+" */5 10-22 * * *", deviceCronTask.deviceHeatMapStatistics)
			return entryID
		}(),
		// 更新设备活跃状态
		func() cron.EntryID {
			entryID, _ := DeviceCron.AddFunc("@every 15s", deviceCronTask.keepAlive)
			return entryID
		}(),
		// 监测关闭推流
		func() cron.EntryID { //2s执行一次
			entryID, _ := DeviceCron.AddFunc("@every 2s", deviceCronTask.closePushFlowCheck2s)
			return entryID
		}(),
		// 监测关闭云点数据推送
		func() cron.EntryID {
			entryID, _ := DeviceCron.AddFunc("@every 10s", deviceCronTask.closePrimitivePointCloudPush)
			return entryID
		}(),
		// 点云心跳PrimitivePointCloudPushHeartbeat
		func() cron.EntryID {
			entryID, _ := DeviceCron.AddFunc("@every 10s", deviceCronTask.PrimitivePointCloudPushHeartbeat)
			return entryID
		}(),
		// 同步本地缓存至redis缓存
		func() cron.EntryID {
			entryID, _ := DeviceCron.AddFunc("@every 10s", deviceCronTask.globalCache)
			return entryID
		}(),
		// 每隔一个小时进行一次截图（97和98）
		func() cron.EntryID {
			r := rand.New(rand.NewSource(time.Now().UnixNano()))
			second := strconv.Itoa(r.Intn(60))
			entryID, _ := DeviceCron.AddFunc(second+" 0 * * * *", deviceCronTask.screenCap)
			return entryID
		}(),
		// 98音量控制
		func() cron.EntryID {
			entryID, _ := DeviceCron.AddFunc("@every 5m", deviceCronTask.volumeCtl)
			return entryID
		}(),
		// 定时保存设备电量
		func() cron.EntryID {
			entryID, _ := DeviceCron.AddFunc("@every 10m", deviceCronTask.saveDeviceBattery)
			return entryID
		}(),
		// 重启97（当97离线时）
		func() cron.EntryID {
			entryID, _ := DeviceCron.AddFunc("0 */10 * * * *", deviceCronTask.reboot97)
			return entryID
		}(),
		// 早上11点和下午17点，重启98广告屏
		func() cron.EntryID {
			entryID, _ := DeviceCron.AddFunc("0 0 11 * * *", deviceCronTask.reboot98)
			return entryID
		}(),
		func() cron.EntryID {
			entryID, _ := DeviceCron.AddFunc("0 0 17 * * *", deviceCronTask.reboot98)
			return entryID
		}(),
		// 获取95的自动开关机配置
		func() cron.EntryID {
			r := rand.New(rand.NewSource(time.Now().UnixNano()))
			second := strconv.Itoa(r.Intn(60))
			entryID, _ := DeviceCron.AddFunc(second+" */20 * * * *", deviceCronTask.getAutoShutdownTimes)
			return entryID
		}(),
		// 获取95配置
		func() cron.EntryID {
			r := rand.New(rand.NewSource(time.Now().UnixNano()))
			second := strconv.Itoa(r.Intn(60))
			entryID, _ := DeviceCron.AddFunc(second+" */5 * * * *", deviceCronTask.getDDRConfig)
			return entryID
		}(),
		// 95任务补偿调度
		// func() cron.EntryID {
		// 	entryID, _ := DeviceCron.AddFunc("0 */3 * * * *", deviceCronTask.taskRecordSchedule)
		// 	return entryID
		// }(),
	)
	DeviceCronIDs.Store(robotID, entryIDs)
}

// RemoveDeviceSessionCron 会话结束时，清除会话定时任务
func RemoveDeviceSessionCron(robotID string) {
	if data, ok1 := DeviceCronIDs.Load(robotID); ok1 {
		if cronIDs, ok2 := data.([]cron.EntryID); ok2 {
			for _, cronID := range cronIDs {
				DeviceCron.Remove(cronID)
			}
		}
		DeviceCronIDs.Delete(robotID)
	}
}

type DeviceCronTask struct {
	RobotID         string
	ConfigItemTypes []string
}

// KeepAlive 在线状态保活
func (dt *DeviceCronTask) keepAlive() {
	// 更新设备最近活跃时间
	terminal.PushToActiveDeviceList(dt.RobotID, "95")
	// 同步设备记录及状态到redis，供售卖后台使用
	// 包含设备ID，设备唯一识别码，设备所属商户，设备所在省，市，商场，设备最近活跃时间
	// device.LoadDeviceToRedis(dt.RobotID)
}

// 定时获取机器人配置项
func (dt *DeviceCronTask) getConfigItem() {
	common.RobotConfigReq(dt.RobotID, dt.ConfigItemTypes)
}

// 环境因子采样
// 每隔5分钟进行一次采样
func (dt *DeviceCronTask) saveDeviceMetric() {
	if data, found := cache.HGet(define.CacheRobotRTInfo+dt.RobotID, "robot_status"); found {
		if notifyRobotStatus, ok := data.(*robotc.NotifyRobotStatus); ok {
			var data []models.DeviceMetric
			// 充电状态
			bchargingVal := 0
			if notifyRobotStatus.GetBatteryState().GetBcharging() {
				bchargingVal = 1
			}
			data = append(data, models.DeviceMetric{
				RobotID: dt.RobotID,
				Name:    "battery_charging",
				Value:   float64(bchargingVal),
			})
			// 电量
			batteryPercent, _ := decimal.NewFromFloat32(notifyRobotStatus.GetBatteryState().GetPercent()).Truncate(2).Float64()
			data = append(data, models.DeviceMetric{
				RobotID: dt.RobotID,
				Name:    "battery",
				Value:   batteryPercent,
			})

			// cpu占用率
			cpu, _ := decimal.NewFromFloat32(notifyRobotStatus.GetSysInfoCPU()).Truncate(0).Float64()
			data = append(data, models.DeviceMetric{
				RobotID: dt.RobotID,
				Name:    "cpu",
				Value:   cpu,
			})

			// 内存占用率
			mem, _ := decimal.NewFromFloat32(notifyRobotStatus.GetSysInfoMemory()).Truncate(0).Float64()
			data = append(data, models.DeviceMetric{
				RobotID: dt.RobotID,
				Name:    "memory",
				Value:   mem,
			})
			if len(data) > 0 {
				device.SaveDeviceMetricData(data)
			}
		}
	}
}

// 定时保存设备电量
func (dt *DeviceCronTask) saveDeviceBattery() {
	if data, found := cache.HGet(define.CacheRobotRTInfo+dt.RobotID, "robot_status"); found {
		if notifyRobotStatus, ok := data.(*robotc.NotifyRobotStatus); ok {
			// 电量
			batteryPercent, _ := decimal.NewFromFloat32(notifyRobotStatus.GetBatteryState().GetPercent()).Truncate(2).Float64()
			batteryPercentInt := int8(batteryPercent)
			mysql.NewDB().Model(&models.Device{}).
				Where("robot_id = ?", dt.RobotID).
				Updates(map[string]interface{}{
					"battery": batteryPercentInt,
				})
		}
	}
}

// deviceHeatMapStatistics 热力图统计
func (dt *DeviceCronTask) deviceHeatMapStatistics() {
	if data, found := cache.HGet(define.CacheRobotRTInfo+dt.RobotID, "robot_status"); found {
		if notifyRobotStatus, ok := data.(*robotc.NotifyRobotStatus); ok {
			// 当前正在使用的地图
			currentMap := notifyRobotStatus.GetNavState().GetCurMapName()
			// 当前的位置
			x := notifyRobotStatus.GetNavState().GetPose().GetX()
			y := notifyRobotStatus.GetNavState().GetPose().GetY()
			dir := notifyRobotStatus.GetNavState().GetPose().GetTh()
			// 获取地图信息
			var mapRecord models.DeviceMap
			rowsAffected := mysql.NewDB().Model(&models.DeviceMap{}).
				Where("robot_id = ?", dt.RobotID).
				Where("map_name = ?", currentMap).
				Where("deleted_at = ?", 0).
				Take(&mapRecord).RowsAffected
			// 保存至数据库
			if rowsAffected > 0 {
				mapName := currentMap + "(" + time.Unix(mapRecord.CreatedAt, 0).Format("01-02") + ")"
				dao.Heatmap{}.Create(context.Background(), dal.Q, dt.RobotID, x, y, dir, mapRecord.ID, mapName)
			}
		}
	}
}

// closePushFlowCheck 关闭推流 - 2s检查一次
// 不在远程监控时，关闭推流
// 这里通过两个状态（订阅且正在推流-（假+真）），用以避免当被订阅时，频繁发送关闭指令。
func (dt *DeviceCronTask) closePushFlowCheck2s() {
	redisCtx, redisCancel := context.WithTimeout(context.Background(), time.Second*3)
	defer redisCancel()
	// 回充摄像头
	{
		cameraType := 1
		underMonitoring, _ := redis.NewDB().Exists(redisCtx, define.RedisISUnderMonitoring+dt.RobotID+":"+strconv.Itoa(cameraType)).Result()
		isPushingFlow, _ := redis.NewDB().HExists(redisCtx, define.RedisRobotRTInfo+dt.RobotID, define.IsPushingFlow+"-"+strconv.Itoa(cameraType)).Result()
		if underMonitoring <= 0 && isPushingFlow {
			cmd := &robotc.PushFlowCMD{}
			cmd.NPushStatus = 0
			cmd.CamType = int32(cameraType) // 回充摄像头
			// 额外数据
			exData := &robotc.CmdExtend{}
			exData.LlTimeStamp = time.Now().UnixMilli()
			exData.StrUserName = []byte("admin")
			cmd.ExData = exData
			msgFullName := string(cmd.ProtoReflect().Descriptor().FullName())
			msgContent, _ := proto.Marshal(cmd)
			pubsub.LocalMsgPublish(dt.RobotID, "95", "wildmsg", msgFullName, msgContent, "")
			redis.NewDB().HDel(redisCtx, define.RedisRobotRTInfo+dt.RobotID, define.IsPushingFlow+"-"+strconv.Itoa(cameraType))
		}
	}
	// rgbd摄像头
	{
		cameraType := 2
		underMonitoring, _ := redis.NewDB().Exists(redisCtx, define.RedisISUnderMonitoring+dt.RobotID+":"+strconv.Itoa(cameraType)).Result()
		isPushingFlow, _ := redis.NewDB().HExists(redisCtx, define.RedisRobotRTInfo+dt.RobotID, define.IsPushingFlow+"-"+strconv.Itoa(cameraType)).Result()
		if underMonitoring <= 0 && isPushingFlow {
			cmd := &robotc.PushFlowCMD{}
			cmd.NPushStatus = 0
			cmd.CamType = int32(cameraType) // 回充摄像头
			// 额外数据
			exData := &robotc.CmdExtend{}
			exData.LlTimeStamp = time.Now().UnixMilli()
			exData.StrUserName = []byte("admin")
			cmd.ExData = exData
			msgFullName := string(cmd.ProtoReflect().Descriptor().FullName())
			msgContent, _ := proto.Marshal(cmd)
			pubsub.LocalMsgPublish(dt.RobotID, "95", "wildmsg", msgFullName, msgContent, "")
			redis.NewDB().HDel(redisCtx, define.RedisRobotRTInfo+dt.RobotID, define.IsPushingFlow+"-"+strconv.Itoa(cameraType))
		}
	}
	// 前摄像头
	{
		cameraType := 3
		underMonitoring, _ := redis.NewDB().Exists(redisCtx, define.RedisISUnderMonitoring+dt.RobotID+":"+strconv.Itoa(cameraType)).Result()
		isPushingFlow, _ := redis.NewDB().HExists(redisCtx, define.RedisRobotRTInfo+dt.RobotID, define.IsPushingFlow+"-"+strconv.Itoa(cameraType)).Result()
		if underMonitoring <= 0 && isPushingFlow {
			cmd := &robotc.PushFlowCMD{}
			cmd.NPushStatus = 0
			cmd.CamType = int32(cameraType) // 回充摄像头
			// 额外数据
			exData := &robotc.CmdExtend{}
			exData.LlTimeStamp = time.Now().UnixMilli()
			exData.StrUserName = []byte("admin")
			cmd.ExData = exData
			msgFullName := string(cmd.ProtoReflect().Descriptor().FullName())
			msgContent, _ := proto.Marshal(cmd)
			pubsub.LocalMsgPublish(dt.RobotID, "95", "wildmsg", msgFullName, msgContent, "")
			redis.NewDB().HDel(redisCtx, define.RedisRobotRTInfo+dt.RobotID, define.IsPushingFlow+"-"+strconv.Itoa(cameraType))
		}
	}
	// 左摄像头
	{
		cameraType := 4
		underMonitoring, _ := redis.NewDB().Exists(redisCtx, define.RedisISUnderMonitoring+dt.RobotID+":"+strconv.Itoa(cameraType)).Result()
		isPushingFlow, _ := redis.NewDB().HExists(redisCtx, define.RedisRobotRTInfo+dt.RobotID, define.IsPushingFlow+"-"+strconv.Itoa(cameraType)).Result()
		if underMonitoring <= 0 && isPushingFlow {
			cmd := &robotc.PushFlowCMD{}
			cmd.NPushStatus = 0
			cmd.CamType = int32(cameraType) // 回充摄像头
			// 额外数据
			exData := &robotc.CmdExtend{}
			exData.LlTimeStamp = time.Now().UnixMilli()
			exData.StrUserName = []byte("admin")
			cmd.ExData = exData
			msgFullName := string(cmd.ProtoReflect().Descriptor().FullName())
			msgContent, _ := proto.Marshal(cmd)
			pubsub.LocalMsgPublish(dt.RobotID, "95", "wildmsg", msgFullName, msgContent, "")
			redis.NewDB().HDel(redisCtx, define.RedisRobotRTInfo+dt.RobotID, define.IsPushingFlow+"-"+strconv.Itoa(cameraType))
		}
	}
	// 右摄像头
	{
		cameraType := 5
		underMonitoring, _ := redis.NewDB().Exists(redisCtx, define.RedisISUnderMonitoring+dt.RobotID+":"+strconv.Itoa(cameraType)).Result()
		isPushingFlow, _ := redis.NewDB().HExists(redisCtx, define.RedisRobotRTInfo+dt.RobotID, define.IsPushingFlow+"-"+strconv.Itoa(cameraType)).Result()
		if underMonitoring <= 0 && isPushingFlow {
			cmd := &robotc.PushFlowCMD{}
			cmd.NPushStatus = 0
			cmd.CamType = int32(cameraType) // 回充摄像头
			// 额外数据
			exData := &robotc.CmdExtend{}
			exData.LlTimeStamp = time.Now().UnixMilli()
			exData.StrUserName = []byte("admin")
			cmd.ExData = exData
			msgFullName := string(cmd.ProtoReflect().Descriptor().FullName())
			msgContent, _ := proto.Marshal(cmd)
			pubsub.LocalMsgPublish(dt.RobotID, "95", "wildmsg", msgFullName, msgContent, "")
			redis.NewDB().HDel(redisCtx, define.RedisRobotRTInfo+dt.RobotID, define.IsPushingFlow+"-"+strconv.Itoa(cameraType))
		}
	}
}

// PrimitivePointCloudPushHeartbeat 点云推送心跳
// 存在远程监控时，发送云点推送心跳
func (dt *DeviceCronTask) PrimitivePointCloudPushHeartbeat() {
	redisCtx, redisCancel := context.WithTimeout(context.Background(), time.Second*3)
	defer redisCancel()
	RTInfoSubFlagExists, _ := redis.NewDB().Exists(redisCtx, define.RedisRobotRTInfoSubFlag+dt.RobotID).Result()
	if RTInfoSubFlagExists > 0 {
		cmd := &robotc.ReqNotifyPrimitivePointCloud{}
		cmd.BIsgetPrimitivePointCloud = true
		msgFullName := string(cmd.ProtoReflect().Descriptor().FullName())
		msgContent, _ := proto.Marshal(cmd)
		pubsub.LocalMsgPublish(dt.RobotID, "95", "wildmsg", msgFullName, msgContent, "")
	}
}

// closePrimitivePointCloudPush 关闭云点数据推送
// 当未实时信息未被订阅，且正在推送云点数据时，停止关闭云点。
// 这里通过两个状态（订阅且正在推送云点），用以避免当被订阅时，频繁发送关闭指令。
func (dt *DeviceCronTask) closePrimitivePointCloudPush() {
	redisCtx, redisCancel := context.WithTimeout(context.Background(), time.Second*3)
	defer redisCancel()
	RTInfoSubFlagExists, _ := redis.NewDB().Exists(redisCtx, define.RedisRobotRTInfoSubFlag+dt.RobotID).Result()
	isPushingPointCloud, _ := redis.NewDB().HExists(redisCtx, define.RedisRobotRTInfo+dt.RobotID, define.IsPushingPointCloud).Result()
	if RTInfoSubFlagExists <= 0 && isPushingPointCloud {
		cmd := &robotc.ReqNotifyPrimitivePointCloud{}
		cmd.BIsgetPrimitivePointCloud = false
		msgFullName := string(cmd.ProtoReflect().Descriptor().FullName())
		msgContent, _ := proto.Marshal(cmd)
		pubsub.LocalMsgPublish(dt.RobotID, "95", "wildmsg", msgFullName, msgContent, "")
		redis.NewDB().HDel(redisCtx, define.RedisRobotRTInfo+dt.RobotID, define.IsPushingPointCloud)
	}
}

// globalCache 缓存信息到全局缓存中
// 缓存模式信息
// 缓存位置信息
func (dt *DeviceCronTask) globalCache() {
	modeVal, _ := cache.HGet(define.CacheRobotRTInfo+dt.RobotID, "mode")
	subModeVal, _ := cache.HGet(define.CacheRobotRTInfo+dt.RobotID, "sub_mode")
	positionXVal, _ := cache.HGet(define.CacheRobotRTInfo+dt.RobotID, "position_x")
	positionYVal, _ := cache.HGet(define.CacheRobotRTInfo+dt.RobotID, "position_y")
	positionDirectionVal, _ := cache.HGet(define.CacheRobotRTInfo+dt.RobotID, "position_direction")
	mode, _ := modeVal.(int)
	subMode, _ := subModeVal.(int)
	positionX, _ := positionXVal.(float32)
	positionY, _ := positionYVal.(float32)
	positionDirection, _ := positionDirectionVal.(float32)
	// 保存全局信息到redis
	redisCtx, redisCtxCancel := context.WithTimeout(context.Background(), time.Second*3)
	defer redisCtxCancel()
	_, err := redis.NewDB().HSet(
		redisCtx,
		define.RedisRobotRTInfo+dt.RobotID,
		"mode", mode,
		"sub_mode", subMode,
		"position_x", positionX,
		"position_y", positionY,
		"position_direction", positionDirection,
	).Result()
	if err != nil {
		logx.Error(context.Background(), "NotifyRobotStatus2Server,update saveModeToRedisError", logx.String("robot_id", dt.RobotID), logx.Err(err))
	}
}

// 98音量控制
func (dt *DeviceCronTask) volumeCtl() {
	if data, found := cache.HGet(define.CacheRobotRTInfo+dt.RobotID, "robot_status"); found {
		if notifyRobotStatus, ok := data.(*robotc.NotifyRobotStatus); ok {
			// 处于充电模式或
			// 正在充电或
			// 充电电极接触
			if notifyRobotStatus.GetNavState().GetMode() == 6 ||
				notifyRobotStatus.BatteryState.Bcharging ||
				notifyRobotStatus.GetGPIOState().GetRchgConnected() > 0 {
				volumeSettingReq := &devicec.VolumeSettingReq{}
				volumeSettingReq.Percent = 0
				volumeSettingReq.Volumetype = 1

				// 关闭98语音播报
				sendMsg := &devicec.Msg{}
				sendMsg.Ack = 0
				sendMsg.Seq = helper.RandString(16)
				sendMsg.Name = string(volumeSettingReq.ProtoReflect().Descriptor().FullName())
				sendMsg.Content, _ = proto.Marshal(volumeSettingReq)
				// protobuf序列化
				bytes, _ := proto.Marshal(sendMsg)
				pubsub.CMDPublish(dt.RobotID, "98", "msg", base64.StdEncoding.EncodeToString(bytes))
			}
		}
	}
}

// screenShot 屏幕截图
// 这里是针对97、98的整点截图
func (dt *DeviceCronTask) screenCap() {
	terminal.Screencap(context.Background(), dt.RobotID, "97", "1")
	terminal.Screencap(context.Background(), dt.RobotID, "98", "1")
}

// reboot97 重启97
// 通过adb实现
func (dt *DeviceCronTask) reboot97() {
	var count int64
	mysql.NewDB().Model(&models.Terminal{}).
		Where("robot_id = ?", dt.RobotID).
		Where("latest_active_time < ?", time.Now().Unix()-600).
		Where("latest_active_time > ?", time.Now().Unix()-1800).
		Count(&count)
	if count == 1 {
		terminal.SendShellCMDTo95(dt.RobotID, []string{
			"adb disconnect",           // 断开所有的adb连接
			"adb connect 192.168.0.97", // 连接97
			"adb reboot",               // 重启97
		}, 10)
	}
}

// reboot98 重启98
func (dt *DeviceCronTask) reboot98() {
	go func() {
		// 先关闭屏幕
		WildmsgSetDeviceOpt(dt.RobotID, 0x30, 0x05)
		// 等待3s
		time.Sleep(time.Second * 3)
		// 再开启
		WildmsgSetDeviceOpt(dt.RobotID, 0x33, 0x05)
	}()
}

// getAutoShutdownTime 获取自动关机的时间组
func (dt *DeviceCronTask) getAutoShutdownTimes() {
	delayMs := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(3000)
	go time.AfterFunc(time.Duration(delayMs)*time.Millisecond, func() {
		reqSwitchMachineConfig := &robotc.ReqSwitchMachineConfig{}
		reqSwitchMachineConfig.OptType = 0 // 获取数据
		databytes, _ := proto.Marshal(reqSwitchMachineConfig)
		pubsub.LocalMsgPublish(
			dt.RobotID,
			"95",
			"wildmsg",
			string(reqSwitchMachineConfig.ProtoReflect().Descriptor().FullName()),
			databytes,
			"",
		)
	})
}

// getDDRConfig 获取95配置
func (dt *DeviceCronTask) getDDRConfig() {
	common.RobotConfigReq(dt.RobotID, []string{"MR_Params.RECHARGING_BATT_LO_PER"}) // 获取低电量阈值配置
}

// taskRecordSchedule 任务记录上报记录上报调度
// 临时运维使用。过期停用
// func (dt *DeviceCronTask) taskRecordSchedule() {
// 	terminal.SendShellCMDTo95(dt.RobotID, []string{
// 		"cd /home/dadao/DDR_Linux/Server/UserData",
// 		"mv $(find ./TaskRecordInfo.bak  -type f | head -n 5) TaskRecordInfo/",
// 	}, 10)
// }
